﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace GTA.UserControls
{
    public partial class UcSearchFilter : BaseUserControl
    {
        #region Local Objects
        private bool shouldSearch = true;
        #endregion

        #region Starting Control
        public UcSearchFilter()
        {
            InitializeComponent();
        }
        private void UcSearchFilter_Load(object sender, EventArgs e)
        {
            StartControl();
        }
        private void StartControl()
        {
            LoadProjects();
            LoadNonSelectResponsibles();
            if (Program.LoggedUser != null && Program.LoggedUser.UserProfile == BusinessEntity.UserManagement.Profiler.User)
                LoadResponsibles();
        }
        #endregion

        #region Events
        private void lstProjects_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            //Se foi selecionado o item "Todos", efetua a propagação para os itens restantes.
            if (e.Item.Equals(lstProjects.Items[0]))
            {
                shouldSearch = false;
                foreach (ListViewItem item in lstProjects.Items)
                    item.Checked = lstProjects.Items[0].Checked;
                shouldSearch = true;
            }

            if (shouldSearch)
                SelectProject();
        }
        public event Action Responsible_Loading;
        public event Action Responsible_Loaded;
        private void lstProjects_Resize(object sender, EventArgs e)
        {
            lstProjects.Columns[0].Width = lstProjects.Width - 23;
        }
        private void lstResponsibles_Resize(object sender, EventArgs e)
        {
            lstResponsibles.Columns[0].Width = lstProjects.Width - 23;
        }
        #endregion

        #region Delegates
        private delegate List<String> GetListViewItemsDelegate(ListView list);
        private delegate List<Int32> GetListViewItemsByIdDelegate(ListView list);
        private delegate Int32 ListViewCheckedItemsCount(ListView list);
        #endregion

        #region Methods
        private void ClearListCheckedItems(ListView list)
        {
            foreach (ListViewItem item in list.CheckedItems)
                item.Checked = false;
        }
        private void LoadNonSelectResponsibles()
        {
            lstResponsibles.Items.Clear();
            lstResponsibles.Items.Add("Selecione o Projeto");
            lstResponsibles.Enabled = false;
        }
        private void LoadProjects()
        {
            try
            {
                lstProjects.Items.Add("Todos");
                if (Program.LoggedUser != null)
                {
                    if (Program.LoggedUser.UserProfile == BusinessEntity.UserManagement.Profiler.Master)
                    {
                        if (Program.Projects != null)
                            Program.Projects.ForEach(item => lstProjects.Items.Add(item.Name));
                    }
                    else
                    {
                        if (Program.LoggedUser != null)
                            Program.LoggedUser.UserProjects.ForEach(item => lstProjects.Items.Add(item.Name));
                    }
                }
            }
            catch (Exception ex)
            {
                HandleException("Carregar a lista de projetos", ex);
            }
        }
        private void SelectProject()
        {
            if (Program.LoggedUser != null && Program.LoggedUser.UserProfile != BusinessEntity.UserManagement.Profiler.User)
            {
                if (lstProjects.CheckedItems.Count > 0)
                    new Thread(new ThreadStart(LoadResponsibles)).Start();
                else
                    LoadNonSelectResponsibles();
            }
        }
        private void SetListControlEnable(bool status, Control list)
        {
            if (list.InvokeRequired)
                list.Invoke(new Action<bool, Control>(SetListControlEnable), new object[] { status, list });
            else
                list.Enabled = status;
        }
        private void ClearListView(ListView list)
        {
            if (list.InvokeRequired)
                list.Invoke(new Action<ListView>(ClearListView), new object[] { list });
            else
                list.Items.Clear();
        }
        private void AddListViewItem(ListView list, ListViewItem item)
        {
            if (list.InvokeRequired)
                list.Invoke(new Action<ListView, ListViewItem>(AddListViewItem), new object[] { list, item });
            else
                list.Items.Add(item);
        }
        private List<String> GetListViewCheckedItems(ListView list)
        {
            if (list.InvokeRequired)
                return list.Invoke(new GetListViewItemsDelegate(GetListViewCheckedItems), new object[] { list }) as List<String>;
            else
            {
                List<String> items = new List<string>();
                foreach (ListViewItem checkedItem in list.CheckedItems)
                    items.Add(checkedItem.Text);
                return items;
            }
        }
        private List<Int32> GetListViewCheckedItemsByID(ListView list)
        {
            if (list.InvokeRequired)
                return list.Invoke(new GetListViewItemsByIdDelegate(GetListViewCheckedItemsByID), new object[] { list }) as List<Int32>;
            else
            {
                List<Int32> items = new List<Int32>();
                foreach (ListViewItem checkedItem in list.CheckedItems)
                {
                    if (checkedItem.Tag != null)
                        items.Add(Convert.ToInt32(checkedItem.Tag));
                }
                return items;
            }
        }
        private List<String> GetListViewItems(ListView list)
        {
            if (list.InvokeRequired)
                return list.Invoke(new GetListViewItemsDelegate(GetListViewItems), new object[] { list }) as List<String>;
            else
            {
                List<String> items = new List<string>();
                foreach (ListViewItem listItem in list.Items)
                    items.Add(listItem.Text);
                return items;
            }
        }
        private Int32 GetListViewCheckedItemsCount(ListView list)
        {
            if (list.InvokeRequired)
                return (int)list.Invoke(new ListViewCheckedItemsCount(GetListViewCheckedItemsCount), new object[] { list });
            else
                return list.CheckedItems.Count;
        }
        private void SetListViewItemCheckState(ListView list, String item, bool state)
        {
            if (list.InvokeRequired)
                list.Invoke(new Action<ListView, String, bool>(SetListViewItemCheckState), new object[] { list, item, state });
            else
            {
                foreach (ListViewItem listItem in list.Items)
                {
                    if (listItem.Text.CompareTo(item) == 0)
                    {
                        listItem.Checked = state;
                        break;
                    }
                }
            }
        }
        private void LoadResponsibles()
        {
            try
            {
                if (Responsible_Loading != null)
                    Responsible_Loading();

                if (Program.LoggedUser.UserProfile != BusinessEntity.UserManagement.Profiler.User)
                {
                    SetListControlEnable(false, lstResponsibles);
                    SetListControlEnable(false, lstProjects);
                    List<BusinessEntity.UserManagement.User> selectedItems = GetSelectedResponsibles();

                    ClearListView(lstResponsibles);
                    AddListViewItem(lstResponsibles, new ListViewItem("CARREGANDO"));

                    BusinessLogic.GTA bl = new BusinessLogic.GTA();
                    List<BusinessEntity.Project> selectedProjects = GetSelectedProjects();
                    List<BusinessEntity.UserManagement.User> users = bl.ListUsers(selectedProjects);
                    if (users != null && users.Count > 0)
                    {
                        ClearListView(lstResponsibles);
                        SetListControlEnable(false, lstResponsibles);
                        foreach (BusinessEntity.UserManagement.User item in users)
                        {
                            ListViewItem listItem = new ListViewItem(item.Name);
                            listItem.Tag = item.ID;
                            AddListViewItem(lstResponsibles, listItem);
                        }
                    }

                    if (selectedItems != null && selectedItems.Count > 0)
                    {
                        foreach (BusinessEntity.UserManagement.User itemSelected in selectedItems)
                        {
                            foreach (String listItem in GetListViewItems(lstResponsibles))
                            {
                                if (listItem.CompareTo(itemSelected.Name) == 0)
                                {
                                    SetListViewItemCheckState(lstResponsibles, listItem, true);
                                    break;
                                }
                            }
                        }
                    }
                    SetListControlEnable(true, lstResponsibles);
                    SetListControlEnable(true, lstProjects);
                }
                else
                {
                    ClearListView(lstResponsibles);
                    ListViewItem listItem = new ListViewItem(Program.LoggedUser.Name);
                    listItem.Checked = true;
                    listItem.Tag = Program.LoggedUser.ID;
                    AddListViewItem(lstResponsibles, listItem);
                    SetListControlEnable(false, lstResponsibles);
                }
            }
            catch (Exception ex)
            {
                SetListControlEnable(true, lstResponsibles);
                SetListControlEnable(true, lstProjects);
                HandleException("Carregar a lista de responsávels", ex);
            }
            finally
            {
                if (Responsible_Loaded != null)
                    Responsible_Loaded();
            }
        }
        public void CleanFilter()
        {
            shouldSearch = false;
            ClearListCheckedItems(lstProjects);
            if (Program.LoggedUser.UserProfile == BusinessEntity.UserManagement.Profiler.Master)
                LoadNonSelectResponsibles();
            shouldSearch = true;
        }
        public List<BusinessEntity.Project> GetSelectedProjects()
        {
            List<BusinessEntity.Project> selectedProjects = null;
            if (GetListViewCheckedItemsCount(lstProjects) > 0)
            {
                selectedProjects = new List<GTA.BusinessEntity.Project>();
                foreach (String listItem in GetListViewCheckedItems(lstProjects))
                {
                    if (listItem.ToLowerInvariant().CompareTo("todos") != 0)
                    {
                        BusinessEntity.Project projectFound = Program.Projects.Find(item => item.Name.CompareTo(listItem) == 0);
                        if (projectFound != null)
                            selectedProjects.Add(projectFound);
                    }
                }
            }
            return selectedProjects;
        }
        public List<BusinessEntity.UserManagement.User> GetSelectedResponsibles()
        {
            List<BusinessEntity.UserManagement.User> users = null;
            if (GetListViewCheckedItemsCount(lstResponsibles) > 0)
            {
                users = new List<GTA.BusinessEntity.UserManagement.User>();
                foreach (String item in GetListViewCheckedItems(lstResponsibles))
                    users.Add(new GTA.BusinessEntity.UserManagement.User(item));
            }
            return users;
        }
        public List<BusinessEntity.UserManagement.User> GetSelectedResponsiblesByID()
        {
            List<BusinessEntity.UserManagement.User> users = null;
            if (GetListViewCheckedItemsCount(lstResponsibles) > 0)
            {
                users = new List<GTA.BusinessEntity.UserManagement.User>();
                foreach (Int32 item in GetListViewCheckedItemsByID(lstResponsibles))
                    users.Add(new GTA.BusinessEntity.UserManagement.User(item));
            }
            return users;
        }
        public void RestoreSearchFilterProjects(List<GTA.BusinessEntity.Configuration.ProjectFilter> list)
        {
            if (list != null &&
                list.Count > 0)
            {
                shouldSearch = false;
                foreach (ListViewItem lstItem in lstProjects.Items)
                {
                    if (list.Exists(it => it.Name.CompareTo(lstItem.SubItems[0].Text) == 0))
                        lstItem.Checked = true;
                }
                shouldSearch = true;
                LoadResponsibles();
            }
        }
        public void RestoreSearchFilterResponsibles(List<GTA.BusinessEntity.Configuration.UserFilter> list)
        {
            if (Program.LoggedUser.UserProfile == BusinessEntity.UserManagement.Profiler.Master &&
                list != null &&
                list.Count > 0)
            {
                foreach (ListViewItem lstItem in lstResponsibles.Items)
                {
                    if (list.Exists(it => it.Name.CompareTo(lstItem.SubItems[0].Text) == 0))
                        lstItem.Checked = true;
                }
            }
        }
        #endregion
    }
}
